package com.ali.common;

import org.apache.tomcat.util.codec.binary.Base64;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class URLConnectionUtil {
    /**
     * Http的Get请求
     */
    public static Map<String, Object> httpGet(String url, Map<String, String> headers) {
        return httpGet(url, headers, false);
    }

    /**
     * Http的Get请求
     */
    public static Map<String, Object> httpGet(String url, Map<String, String> headers, boolean isFile) {
        Map<String, Object> response = null;

        HttpURLConnection httpURLConnection = null;
        try {
            httpURLConnection = getHttpURLConnection(url, headers);
            //设置请求方式
            httpURLConnection.setRequestMethod("GET");
            //设置是否传输参数
            httpURLConnection.setDoOutput(false);
            //设置是否获取参数
            httpURLConnection.setDoInput(true);

            //连接
            httpURLConnection.connect();

            response = getResponse(httpURLConnection, isFile);
        } catch (Exception e) {
            e.fillInStackTrace();
        } finally {
            if (httpURLConnection != null) {
                httpURLConnection.disconnect();
            }
        }

        return response;
    }

    /**
     * 获取HttpURLConnection
     */
    private static HttpURLConnection getHttpURLConnection(String url, Map<String, String> headers) {
        try {
            URL httpUrl = new URL(url);

            HttpURLConnection httpURLConnection = (HttpURLConnection) httpUrl.openConnection();
            //设置是否获取参数
            httpURLConnection.setDoInput(true);
            //设置是否使用缓存
            httpURLConnection.setUseCaches(true);
            //设置是否自动执行HTTP重定向
            httpURLConnection.setInstanceFollowRedirects(true);
            //设置超时时间，3000毫秒
            httpURLConnection.setConnectTimeout(3000);

            //设置请求头
            if (headers != null) {
                for (String key : headers.keySet()) {
                    httpURLConnection.setRequestProperty(key, headers.get(key));
                }
            }

            return httpURLConnection;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取返回信息
     */
    private static Map<String, Object> getResponse(HttpURLConnection httpURLConnection, boolean isFile) throws IOException {
        Map<String, Object> result = new HashMap<>();

        InputStream inputStream = null;
        try {
            //获取响应码
            int responseCode = httpURLConnection.getResponseCode();
            result.put("responseCode", responseCode);

            //获取返回参数
            inputStream = httpURLConnection.getInputStream();
            byte[] responseByte = StreamUtil.readInputStream(inputStream);

            String response;
            if (isFile) {
                response = Base64.encodeBase64String(responseByte);
            } else {
                response = new String(responseByte, StandardCharsets.UTF_8);
            }
            result.put("response", response);

            //获取返回头
            Map<String, List<String>> headerFields = httpURLConnection.getHeaderFields();
            for (String key : headerFields.keySet()) {
                result.put(key, headerFields.get(key));
            }
        } catch (Exception e) {
            e.fillInStackTrace();
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
        }

        return result;
    }

    /**
     * Http的Post请求
     */
    public static Map<String, Object> httpPost(String url, String content, Map<String, String> headers) {
        return httpPost(url, content, headers, false);
    }

    /**
     * Http的Post请求
     */
    public static Map<String, Object> httpPost(String url, String content, Map<String, String> headers, boolean isFile) {
        Map<String, Object> response = null;

        HttpURLConnection httpURLConnection = null;
        OutputStream outputStream = null;
        try {
            httpURLConnection = getHttpURLConnection(url, headers);
            //设置请求方式
            httpURLConnection.setRequestMethod("POST");
            //设置是否传输参数
            httpURLConnection.setDoOutput(true);
            //设置传输参数格式
            httpURLConnection.setRequestProperty("Content-Type", "application/json");

            //连接
            httpURLConnection.connect();

            //传输参数
            outputStream = httpURLConnection.getOutputStream();
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
            outputStreamWriter.append(content);
            outputStreamWriter.flush();

            response = getResponse(httpURLConnection, isFile);
        } catch (Exception e) {
            e.fillInStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.fillInStackTrace();
                }
            }
            if (httpURLConnection != null) {
                httpURLConnection.disconnect();
            }
        }

        return response;
    }

    /**
     * Https的Get请求
     */
    public static Map<String, Object> httpsGet(String url, Map<String, String> headers) {
        return httpsGet(url, headers, false);
    }

    /**
     * Https的Get请求
     */
    public static Map<String, Object> httpsGet(String url, Map<String, String> headers, boolean isFile) {
        Map<String, Object> response = null;

        HttpsURLConnection httpsURLConnection = null;
        try {
            httpsURLConnection = getHttpsURLConnection(url, headers);
            //设置请求方式
            httpsURLConnection.setRequestMethod("GET");
            //设置是否传输参数
            httpsURLConnection.setDoOutput(false);
            //设置是否获取参数
            httpsURLConnection.setDoInput(true);

            //连接
            httpsURLConnection.connect();

            response = getResponse(httpsURLConnection, isFile);
        } catch (Exception e) {
            e.fillInStackTrace();
        } finally {
            if (httpsURLConnection != null) {
                httpsURLConnection.disconnect();
            }
        }

        return response;
    }

    /**
     * 获取HttpsURLConnection
     */
    private static HttpsURLConnection getHttpsURLConnection(String url, Map<String, String> headers) {
        try {
            URL httpUrl = new URL(url);

            HttpsURLConnection httpsURLConnection = (HttpsURLConnection) httpUrl.openConnection();
            //设置是否获取参数
            httpsURLConnection.setDoInput(true);
            //设置是否使用缓存
            httpsURLConnection.setUseCaches(true);
            //设置是否自动执行HTTP重定向
            httpsURLConnection.setInstanceFollowRedirects(true);
            //设置超时时间，3000毫秒
            httpsURLConnection.setConnectTimeout(3000);

            //设置请求头
            if (headers != null) {
                for (String key : headers.keySet()) {
                    httpsURLConnection.setRequestProperty(key, headers.get(key));
                }
            }

            MyHostnameVerifier myHostnameVerifier = new MyHostnameVerifier();
            httpsURLConnection.setHostnameVerifier(myHostnameVerifier);

            SSLContext sslContext = SSLContext.getInstance("SSL");
            TrustManager[] tm = {new MyX509TrustManager()};
            SecureRandom secureRandom = new SecureRandom();
            sslContext.init(null, tm, secureRandom);
            SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
            httpsURLConnection.setSSLSocketFactory(sslSocketFactory);

            return httpsURLConnection;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Https的Post请求
     */
    public static Map<String, Object> httpsPost(String url, String content, Map<String, String> headers, boolean isFile) {
        Map<String, Object> response = null;

        HttpsURLConnection httpsURLConnection = null;
        OutputStream outputStream = null;
        try {
            httpsURLConnection = getHttpsURLConnection(url, headers);
            //设置请求方式
            httpsURLConnection.setRequestMethod("POST");
            //设置是否传输参数
            httpsURLConnection.setDoOutput(true);
            //设置传输参数格式
            httpsURLConnection.setRequestProperty("Content-Type", "application/json");

            //连接
            httpsURLConnection.connect();

            //传输参数
            outputStream = httpsURLConnection.getOutputStream();
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
            outputStreamWriter.append(content);
            outputStreamWriter.flush();

            response = getResponse(httpsURLConnection, isFile);
        } catch (Exception e) {
            e.fillInStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.fillInStackTrace();
                }
            }
            if (httpsURLConnection != null) {
                httpsURLConnection.disconnect();
            }
        }

        return response;
    }
}